﻿#include "TcpClient.h"
#include <QByteArray>
#include <QDebug>
#include <qmessagebox.h>
#include <QHostAddress>

TcpClient::TcpClient(QWidget* parent)
	: QWidget(parent)
{
	m_bDownloadFile = false;
	ui.setupUi(this);
	//替换弹出窗口大小
	//resize(500, 250);

	loadConfig();

	//信号 TcpClient::connected() 槽 TcpClient::showconnect()
	connect(&m_tcpSocket, SIGNAL(connected())
		, this, SLOT(showConnect()));

	//信号 TcpClient::readyRead() 槽 TcpClient::readReady()
	connect(&m_tcpSocket, SIGNAL(readyRead())
		, this, SLOT(recvMsg()));

	/**
	* 另一种连接方式
	connect(&m_tcpSocket, &QTcpSocket::readyRead, [=]() {
		//接收服务器发送的数据
		QByteArray resvMessage = m_tcpSocket.readAll();
		qDebug() << "接受到的message：" << resvMessage;

		});
	*/

	//将本客户机通过ip,prot连接服务器
	m_tcpSocket.connectToHost((QHostAddress(m_strIP)), m_usPort);

}

TcpClient::~TcpClient()
{}

//载入配置文件(IP地址及端口号)
void TcpClient::loadConfig()
{
	QFile file(":/client.config");
	if (file.open(QIODevice::ReadOnly)) {
		QByteArray baData = file.readAll();
		QString strData = baData.toStdString().c_str();
		//qDebug() << strData;
		file.close();

		strData.replace("\r\n", " ");
		//qDebug() << strData;
		QStringList strList = strData.split(" ");
		m_strIP = strList.at(0);
		m_usPort = strList.at(1).toUShort();
		qDebug() << "ip:" << m_strIP << " port:" << m_usPort << endl;
	}
	else {
		QMessageBox::critical(this, "open config", "open config failed");
	}
}

TcpClient& TcpClient::getInstance()
{
	static TcpClient instance;
	return instance;
}

QTcpSocket& TcpClient::getTcpSocket()
{
	return m_tcpSocket;
	// TODO: 在此处插入 return 语句
}

QString TcpClient::getCurPath()
{
	return m_strCurPath;
}

void TcpClient::setCurPath(QString strNewPath)
{
	m_strCurPath = strNewPath;
	return;
}

QString TcpClient::getStrName() {
	return strName;
}

bool TcpClient::getDownloadState()
{
	return m_bDownloadFile;
}

void TcpClient::setDownloadState(bool state)
{
	m_bDownloadFile = state;
}

//弹出连接成功窗口
void TcpClient::showConnect() {
	QMessageBox::information(this, "connecting to server", "connection succeeded");
}

//点击注册按钮后触发该函数
void TcpClient::on_regist_pb_clicked()
{
	QString strName = ui.name_le->text();
	QString strPwd = ui.pwd_le->text();
	{//print test: show what user input
		qDebug() << "\nusr name:" << strName << "\nusr  pwd:" << strPwd;
	}
	if (!strName.isEmpty() && !strPwd.isEmpty()) {
		PDU* pdu = mkPDU(0);
		pdu->uiMsgType = ENUM_MESSAGE_TYPE_REGIST_REQUEST;
		strncpy(pdu->caData, strName.toStdString().c_str(), 32);
		strncpy(pdu->caData + 32, strPwd.toStdString().c_str(), 32);
		m_tcpSocket.write((char*)pdu, pdu->uiPDULen);
		free(pdu);
		pdu = NULL;
	}
	else {
		QMessageBox::critical(this, "注册", "注册失败：用户名或密码为空");
	}
}

//点击登录后触发
void TcpClient::on_login_pb_clicked()
{
	QString strName = ui.name_le->text();
	QString strPwd = ui.pwd_le->text();
	{//print test: show what user input
		qDebug() << "\nusr name:" << strName << "\nusr  pwd:" << strPwd;
	}
	if (!strName.isEmpty() && !strPwd.isEmpty()) {
		//*************VIP****************
		this->strName = strName;
		//*************VIP****************
		PDU* pdu = mkPDU(0);
		pdu->uiMsgType = ENUM_MESSAGE_TYPE_LOGIN_REQUEST;
		strncpy(pdu->caData, strName.toStdString().c_str(), 32);
		strncpy(pdu->caData + 32, strPwd.toStdString().c_str(), 32);
		m_tcpSocket.write((char*)pdu, pdu->uiPDULen);
		free(pdu);
		pdu = NULL;
	}
	else {
		QMessageBox::critical(this, "登录", "登录失败，用户名或密码为空");
	}
}

//点击cancel后执行
void TcpClient::on_cancel_pb_clicked()
{

}

//收到来自服务器的socket数据后进行处理
/* 不要在登陆前调用OpeWidget类 */
void TcpClient::recvMsg() {
	if (m_bDownloadFile) {
		QByteArray buffer = m_tcpSocket.readAll();
		Book* pBook = OpeWidget::getInstance().getBook();
		QFile* pFile = pBook->getFileInstance();
		pFile->write(buffer);
		pBook->m_iRecved += buffer.size();
		qDebug() << "接收到：" << pBook->m_iRecved << " 总共为：" << pBook->m_iTotal;
		if (pBook->m_iRecved == pBook->m_iTotal) {	//文件下载成功
			pFile->close();
			pBook->m_iRecved = 0;
			pBook->m_iTotal = 0;
			m_bDownloadFile = false;
			QMessageBox::information(this, "下载文件", "文件下载成功");
		}
		else if (pBook->m_iRecved > pBook->m_iTotal) {
			pFile->close();
			pBook->m_iRecved = 0;
			pBook->m_iTotal = 0;
			m_bDownloadFile = false;
			QMessageBox::critical(this, "下载文件", "下载文件失败：文件大小校验出错");
		}
	}
	else {
		qDebug() << "当前客户机端socket中可读数据：" << m_tcpSocket.bytesAvailable();
		uint uiPDULen = 0;
		m_tcpSocket.read((char*)&uiPDULen, sizeof(uint));
		uint uiMsgLen = uiPDULen - sizeof(PDU);
		PDU* pdu = mkPDU(uiMsgLen);
		m_tcpSocket.read((char*)pdu + sizeof(uint), uiPDULen - sizeof(uint));
		pdu->uiPDULen = uiPDULen;
		switch (pdu->uiMsgType) {

		case ENUM_MESSAGE_TYPE_REGIST_RESPOND: {
			//注册成功
			if (!strcmp(pdu->caData, REGIST_OK)) {
				QMessageBox::information(this, "注册", REGIST_OK);
			}
			else if (!strcmp(pdu->caData, REGIST_FAILED)) {
				QMessageBox::warning(this, "注册", REGIST_FAILED);
			}
			break;
		}
		case ENUM_MESSAGE_TYPE_LOGIN_RESPOND: {
			//登陆成功
			if (!strcmp(pdu->caData, LOGIN_OK)) {
				//***************VIP*******************
				if (QString::localeAwareCompare(strName, QString("胡天娇")) == 0) {
					QMessageBox::information(this, "登录", LOGIN_OK_VIP);
				}
				//***************VIP********************
				else QMessageBox::information(this, "登录", LOGIN_OK);

				//用登录客户的名字拼接为当前目录
				m_strCurPath = QString("./%1").arg(strName);

				//登录成功后跳转界面
				this->hide();
				OpeWidget::getInstance().show();
			}
			else if (!strcmp(pdu->caData, LOGIN_FAILED)) {
				QMessageBox::warning(this, "登录", LOGIN_FAILED);
			}
			break;
		}
		case ENUM_MESSAGE_TYPE_CREATE_DIR_RESPOND: {
			QMessageBox::information(this, "创建文件夹", pdu->caData);
			OpeWidget::getInstance().getBook()->flushFile();
			break;
		}
		case ENUM_MESSAGE_TYPE_FLUSH_FILE_RESPOND: {
			QString enterDir = OpeWidget::getInstance().getBook()->getEnterDir();
			if (!enterDir.isEmpty()) {
				m_strCurPath = m_strCurPath + '/' + enterDir;
				OpeWidget::getInstance().getBook()->clearEnterDir();
			}
			OpeWidget::getInstance().getBook()->updateFileList(pdu);
			break;
		}
		case ENUM_MESSAGE_TYPE_DELETE_DIR_RESPOND: {
			QMessageBox::information(this, "删除文件夹", pdu->caData);
			OpeWidget::getInstance().getBook()->flushFile();
			break;
		}
		case ENUM_MESSAGE_TYPE_RENAME_FILE_RESPOND: {
			QMessageBox::information(this, "重命名文件(夹)", pdu->caData);
			OpeWidget::getInstance().getBook()->flushFile();
			break;
		}
		case ENUM_MESSAGE_TYPE_ENTER_DIR_RESPOND: {
			QMessageBox::information(this, "打开文件夹", pdu->caData);
			OpeWidget::getInstance().getBook()->clearEnterDir();
			break;
		}
		case ENUM_MESSAGE_TYPE_UPLOAD_FILE_RESPOND: {
			QMessageBox::information(this, "上传文件", pdu->caData);
			OpeWidget::getInstance().getBook()->flushFile();
			break;
		}
		case ENUM_MESSAGE_TYPE_DELETE_FILE_RESPOND: {
			QMessageBox::information(this, "删除文件", pdu->caData);
			OpeWidget::getInstance().getBook()->flushFile();
			break;
		}
		case ENUM_MESSAGE_TYPE_DOWNLOAD_FILE_RESPOND: {
			qDebug() << pdu->caData;
			char caFileName[32] = { '\0' };
			sscanf(pdu->caData, "%s %lld", caFileName,
				&(OpeWidget::getInstance().getBook()->m_iTotal));
			if (strlen(caFileName) > 0) {
				m_bDownloadFile = true;
				QFile* m_pFile = OpeWidget::getInstance().getBook()->getFileInstance();
				m_pFile->setFileName(OpeWidget::getInstance().getBook()->getSavePath());
				if (!m_pFile->open(QIODevice::WriteOnly)) {
					QMessageBox::warning(this, "下载文件", "下载失败：文件保存路径出错");
				}
				else {	//文件打开成功，准备接收数据
					PDU* resPdu = mkPDU(0);
					resPdu->uiMsgType = ENUM_MESSAGE_TYPE_DOWNLOAD_FILE_DATA_REQUEST;
					getTcpSocket().write((char*)resPdu, resPdu->uiPDULen);
					free(resPdu);
					resPdu = NULL;
				}
			}
			break;
		}
		case ENUM_MESSAGE_TYPE_ALL_ONLINE_RESPOND: {
			OpeWidget::getInstance().getFriend()->showAllOnlineUsr(pdu);
			break;
		}
		case ENUM_MESSAGE_TYPE_SEARCH_USER_RESPOND: {
			QMessageBox::information(this, "搜索用户", pdu->caData);
			break;
		}
		case ENUM_MESSAGE_TYPE_ADD_FRIEND_REQUEST: {
			//pdu->caData存放name；pdu->caData+32存放perName
			qDebug() << "申请加好友" << pdu->caData;
			int ret = QMessageBox::information(this, "添加好友", QString("[%1]想要添加你为好友").arg(pdu->caData),
				QMessageBox::Yes, QMessageBox::No);
			PDU* resPdu = mkPDU(sizeof(int));
			resPdu->uiMsgType = ENUM_MESSAGE_TYPE_ADD_FRIEND_RESPOND;
			memcpy(resPdu->caData, pdu->caData, 64);
			if (ret == QMessageBox::Yes) {	//同意添加好友
				(resPdu->caMsg)[0] = 1;
			}
			else if (ret == QMessageBox::No) {	//拒绝添加好友
				(resPdu->caMsg)[0] = 0;
			}
			else {	//不做处理，不拒绝也不同意
				(resPdu->caMsg)[0] = -1;
			}
			getTcpSocket().write((char*)resPdu, resPdu->uiPDULen);
			free(resPdu);
			resPdu = NULL;
			break;
		}
		case ENUM_MESSAGE_TYPE_ADD_FRIEND_RESPOND: {
			qDebug() << pdu->caData;
			QMessageBox::information(this, "添加好友", pdu->caData);
			break;
		}
		default:
			break;
		}
		free(pdu);
		pdu = NULL;
	}
	return;
}
